//#preprocess
/*-
 * Copyright (C) 2010 Orangatame LLC.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
//#ifdef BlackBerrySDK6.0.0
package com.google.authenticator.blackberry;

import java.util.Hashtable;
import java.util.Vector;

import javax.microedition.media.MediaException;

import net.rim.device.api.applicationcontrol.ApplicationPermissions;
import net.rim.device.api.applicationcontrol.ApplicationPermissionsManager;
import net.rim.device.api.barcodelib.BarcodeDecoder;
import net.rim.device.api.barcodelib.BarcodeDecoderListener;
import net.rim.device.api.barcodelib.BarcodeScanner;
import net.rim.device.api.system.Characters;
import net.rim.device.api.system.ControlledAccessException;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.container.MainScreen;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.DecodeHintType;

public class BarcodeScanScreen extends MainScreen {
    
    private BarcodeScanner mScanner;
    private AuthenticatorScreen mAuthScreen;
    
    /**
     * Creates a new <c>BarcodeScanScreen</c> object
     */
    public BarcodeScanScreen(AuthenticatorScreen ascreen) {
        mAuthScreen = ascreen;
        // Initialize Hashtable used to inform the scanner how to
        // recognize the QR code format.
        Hashtable hints = new Hashtable(1);
        Vector formats = new Vector(1);
        formats.addElement(BarcodeFormat.QR_CODE);
        hints.put(DecodeHintType.POSSIBLE_FORMATS, formats);

        // Initialize the BarcodeDecoder
        BarcodeDecoder decoder = new BarcodeDecoder(hints);

        // Create a custom instance of a BarcodeDecoderListener to pop the
        // screen and pass the results when a QR code is recognized.
        BarcodeDecoderListener decoderListener = new BarcodeDecoderListener() {
            /**
             * @see BarcodeDecoderListener#barcodeDecoded(String)
             */
            public void barcodeDecoded(String rawText) {
                displayMessage(rawText);
                String uriString = Uri.decode(rawText);
                Uri uri = Uri.parse(uriString);
                if (uri != null) {
                    Dialog.inform(uri.toString());
                  mAuthScreen.parseSecret(uri);
                  mAuthScreen.refreshUserList();
                } else {
                    Dialog.alert("no URI");
                }
            }
        };

        try {
            // Initialize the BarcodeScanner object and add the associated view finder.
            mScanner = new BarcodeScanner(decoder, decoderListener);
            mScanner.getVideoControl().setDisplayFullScreen(true);
            add(mScanner.getViewfinder());

        } catch (Exception e) {
            displayMessage("Error: " + e.getMessage());
        }
    }

    /**
     * Informs the BarcodeScanner that it should begin scanning for QR Codes
     */
    public void startScan() {
        checkPermissions();
        try {
            mScanner.startScan();
        } catch (MediaException me) {
            displayMessage("Error: " + me.getMessage());
        } catch (ControlledAccessException cae) {
            
        }
    }

    /**
     * @see net.rim.device.api.ui.Screen#keyChar()
     */
    protected boolean keyChar(char key, int status, int time) {
        if (key == Characters.ESCAPE) {
            // Manually stop the scanning process and pop the screen
            try {
                mScanner.stopScan();
            } catch (MediaException me) {
                displayMessage("Error: " + me.getMessage());
            }
            if (isDisplayed()) {
                UiApplication.getUiApplication().popScreen(this);
            }
        }

        return super.keyChar(key, status, time);
    }

    /**
     * @see net.rim.device.api.ui.Screen#close()
     */
    public void close() {
        try {
            mScanner.stopScan();
        } catch (MediaException me) {
            displayMessage("Error: " + me.getMessage());
        }
        super.close();
    }

    /**
     * Pops the <c>BarScanScreen</c> and displays text on the main screen
     * 
     * @param text
     *            Text to display on the screen
     */
    private void displayMessage(final String text) {
        UiApplication.getUiApplication().invokeLater(new Runnable() {
            public void run() {
                Dialog.alert(text);
                if (isDisplayed()) {
                    UiApplication.getUiApplication().popScreen(BarcodeScanScreen.this);
                }
            }
        });
    }
    
    /**
     * Check if the {@link ApplicationPermissions#PERMISSION_RECORDING} permission is granted for barcode scanning.
     * If not, prompt the user.
     */
    private void checkPermissions() {
        ApplicationPermissions currentPerms = ApplicationPermissionsManager.getInstance().getApplicationPermissions();
        if (currentPerms.getPermission(ApplicationPermissions.PERMISSION_RECORDING) != ApplicationPermissions.VALUE_ALLOW) {
            ApplicationPermissions request = new ApplicationPermissions();
            request.addPermission(ApplicationPermissions.PERMISSION_RECORDING);
            ApplicationPermissionsManager.getInstance().invokePermissionsRequest(request);
        }
    }
}
//#endif
